In [2]:
import numpy
n = 10
A = numpy.random.random(n)
print(A)
In [2]:
s = 0
for i in range(n):
s += A[i]
print(s)
In [3]:
s = numpy.sum(A)
print(s)
Une préférence ?
In [4]:
n = 1000000
A = numpy.random.random(n)
def explicit_sum(seq):
s = 0
for elem in seq:
s += elem ** 2
return s
%timeit explicit_sum(A)
In [6]:
%timeit numpy.sum(A**2)
In [ ]:
### Cython
In [41]:
%load_ext Cython
In [8]:
%%cython
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
def cython_sum(np.ndarray[double, ndim=1] A):
cdef double s = 0
cdef int i, n
n = len(A)
for i in range(n):
s += A[i] * A[i]
return s
In [9]:
%timeit cython_sum(A)
In [11]:
%%file pythran_sum.py
#pythran export pythran_sum(float64[])
import numpy
def pythran_sum(A):
return numpy.sum(A**2)
In [12]:
!python -m pythran.run pythran_sum.py -DUSE_BOOST_SIMD -O3 -march=native
In [14]:
!python -m timeit -s 'from pythran_sum import pythran_sum; import numpy; n = 1000000 ; A = numpy.random.random(n)' 'pythran_sum(A)'
In [16]:
n, m = 100, 200
A = numpy.random.random((n,m))
In [19]:
s = 0.
for i in range(1, n-1):
for j in range(1, m-1):
s += A[i,j]
print(s)
In [21]:
print(numpy.sum(A[1:-1, 1:-1]))
In [22]:
s = 0
for i in range(n):
for j in range(m):
if A[i,j] < .5:
s += 1
print(s)
In [23]:
print(numpy.sum(A < .5))
In [25]:
s = 0
B = numpy.empty_like(A)
for i in range(n):
for j in range(m):
if A[i,j] < .5:
B[i,j] = A[i,j]
else:
B[i,j] = 0.
print(B)
In [26]:
print(numpy.where(A<.5,A,0.))
In [27]:
### Piège!
In [33]:
n = 100
B = numpy.arange(100)
shift = 3
for i in range(shift, n):
B[i] = 1 + B[i - shift]
print(B)
In [35]:
B = numpy.arange(100)
B[shift:] = 1 + B[:-shift]
print(B)
In [45]:
%%file grayscott.py
#pythran export GrayScott(int, float, float, float, float)
import numpy as np
def GrayScott(counts, Du, Dv, F, k):
n = 300
U = np.zeros((n+2,n+2), dtype=np.float32)
V = np.zeros((n+2,n+2), dtype=np.float32)
u, v = U[1:-1,1:-1], V[1:-1,1:-1]
r = 20
u[:] = 1.0
U[n/2-r:n/2+r,n/2-r:n/2+r] = 0.50
V[n/2-r:n/2+r,n/2-r:n/2+r] = 0.25
u += 0.15*np.random.random((n,n))
v += 0.15*np.random.random((n,n))
for i in range(counts):
Lu = ( U[0:-2,1:-1] +
U[1:-1,0:-2] - 4*U[1:-1,1:-1] + U[1:-1,2:] +
U[2: ,1:-1] )
Lv = ( V[0:-2,1:-1] +
V[1:-1,0:-2] - 4*V[1:-1,1:-1] + V[1:-1,2:] +
V[2: ,1:-1] )
uvv = u*v*v
u += Du*Lu - uvv + F*(1 - u)
v += Dv*Lv + uvv - (F + k)*v
return V
In [38]:
from grayscott import GrayScott
In [39]:
%timeit GrayScott(40, 0.16, 0.08, 0.04, 0.06)
In [42]:
%%cython
cimport cython
import numpy as np
cimport numpy as np
cpdef CythonGrayScott(int counts, double Du, double Dv, double F, double k):
cdef int n = 300
cdef np.ndarray U = np.zeros((n+2,n+2), dtype=np.float_)
cdef np.ndarray V = np.zeros((n+2,n+2), dtype=np.float_)
cdef np.ndarray u = U[1:-1,1:-1]
cdef np.ndarray v = V[1:-1,1:-1]
cdef int r = 20
u[:] = 1.0
U[n/2-r:n/2+r,n/2-r:n/2+r] = 0.50
V[n/2-r:n/2+r,n/2-r:n/2+r] = 0.25
u += 0.15*np.random.random((n,n))
v += 0.15*np.random.random((n,n))
cdef np.ndarray Lu = np.zeros_like(u)
cdef np.ndarray Lv = np.zeros_like(v)
cdef int i, c, r1, c1, r2, c2
cdef double uvv
cdef double[:, ::1] bU = U
cdef double[:, ::1] bV = V
cdef double[:, ::1] bLu = Lu
cdef double[:, ::1] bLv = Lv
for i in range(counts):
for r in range(n):
r1 = r + 1
r2 = r + 2
for c in range(n):
c1 = c + 1
c2 = c + 2
bLu[r,c] = bU[r1,c2] + bU[r1,c] + bU[r2,c1] + bU[r,c1] - 4*bU[r1,c1]
bLv[r,c] = bV[r1,c2] + bV[r1,c] + bV[r2,c1] + bV[r,c1] - 4*bV[r1,c1]
for r in range(n):
r1 = r + 1
for c in range(n):
c1 = c + 1
uvv = bU[r1,c1]*bV[r1,c1]*bV[r1,c1]
bU[r1,c1] += Du*bLu[r,c] - uvv + F*(1 - bU[r1,c1])
bV[r1,c1] += Dv*bLv[r,c] + uvv - (F + k)*bV[r1,c1]
return V
In [61]:
%timeit GrayScott(40, 0.16, 0.08, 0.04, 0.06)
%timeit CythonGrayScott(40, 0.16, 0.08, 0.04, 0.06)
In [62]:
!python -m pythran.run -O3 -march=native grayscott.py -o pythran_grayscott.so
In [63]:
! python -m timeit -s 'from pythran_grayscott import GrayScott' 'GrayScott(40, 0.16, 0.08, 0.04, 0.06)'
with pip install pythran
In [ ]: